
<template>
  <div class="box">
    <div class="option">
      <button @click="addBillboard">标记点</button>
      <button @click="drawWater">绘制水面波浪效果</button>
      <button>TODO：淹没分析</button>
      <button @click="createThermodynamicDiagram">热力图</button>
    </div>
    <div id="cesiumContainer"></div>
  </div>
</template>

<script>
// 加载 Cesium
import * as Cesium from 'cesium'
import 'cesium/Build/Cesium/Widgets/widgets.css'
// 加载 heatmap
import Heatmap from 'heatmap.js'

var viewer // 视图
var handler // 点击事件
export default {
  name: 'CesiumContainer',
  mounted() {
    this.initHandle()
  },
  methods: {
    /* *********************初始化 start********************* */
    initHandle() {
      var viewerOption = {
        geocoder: false, // 地理位置查询定位控件
        homeButton: false, // 默认相机位置控件
        timeline: false, // 时间滚动条控件
        navigationHelpButton: false, // 默认的相机控制提示控件
        fullscreenButton: false, // 全屏控件
        scene3DOnly: true, // 每个几何实例仅以3D渲染以节省GPU内存
        baseLayerPicker: false, // 底图切换控件
        animation: false // 控制场景动画的播放速度控件
      }
      Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI3ZjA2ZDQ2ZS02NTA4LTQ2NTItODE1My1kZjE3MjBkMjFkNzAiLCJpZCI6NDM5NCwic2NvcGVzIjpbImFzciIsImdjIl0sImlhdCI6MTU0MDcyNzI4Nn0.L7P8pJponZfYjdsGnEw2hIHd2AN0h-SuYl6XvzOwLeA'
      viewer = new Cesium.Viewer('cesiumContainer', viewerOption)
      // 隐藏 LOGO 版权
      viewer._cesiumWidget._creditContainer.style.display = 'none'
      // 加载底图
      viewer.imageryLayers.addImageryProvider(
        new Cesium.ArcGisMapServerImageryProvider({
          url: 'http://cache1.arcgisonline.cn/ArcGIS/rest/services/ChinaOnlineCommunity/MapServer'
        })
      )

      // 去掉entity的点击事件 start
      viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK)
      viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK)
      // 去掉entity的点击事件 end

      // 如果为真，则允许用户旋转相机。如果为假，相机将锁定到当前标题。此标志仅适用于2D和3D。
      // viewer.scene.screenSpaceCameraController.enableRotate = false
      // // 如果为true，则允许用户平移地图。如果为假，相机将保持锁定在当前位置。此标志仅适用于2D和Columbus视图模式。
      // viewer.scene.screenSpaceCameraController.enableTranslate = false
      // // 如果为真，允许用户放大和缩小。如果为假，相机将锁定到距离椭圆体的当前距离
      // viewer.scene.screenSpaceCameraController.enableZoom = false
      // // 如果为真，则允许用户倾斜相机。如果为假，相机将锁定到当前标题。这个标志只适用于3D和哥伦布视图。
      // viewer.scene.screenSpaceCameraController.enableTilt = false

      // 处理用户输入事件
      handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas)
      // 鼠标左键
      handler.setInputAction(function(click) {
        var pick = viewer.scene.pick(click.position)
        console.log(pick, 'pcik')
        // 选中某模型 pick 选中的对象
        if (pick && pick.id) {
          alert(pick.id._code)
        }
      }, Cesium.ScreenSpaceEventType.LEFT_CLICK)
    },
    /* *********************初始化 end********************* */
    /* *********************标点 start********************* */
    addBillboard() {
      viewer.entities.add({
        // name: '风机设备',
		    code: '123456789',
        position: Cesium.Cartesian3.fromDegrees(121.54035, 38.92146, 50),
        // point: { // 点
        //   pixelSize: 0,
        //   color: Cesium.Color.RED,
        //   outlineColor: Cesium.Color.WHITE,
        //   outlineWidth: 2
		    // },
		    // label: { // 文字标签
        //   text: '风机设备',
        //   font: '14pt monospace',
        //   style: Cesium.LabelStyle.FILL,
        //   outlineWidth: 2,
        //   verticalOrigin: Cesium.VerticalOrigin.BOTTOM, // 垂直方向以底部来计算标签的位置
        //   pixelOffset: new Cesium.Cartesian2(0, -9) // 偏移量
		    // },
        billboard: { // 图标
          image: require('../../images/blueCamera.png'), // default: undefined
          // show: true, // default
          // pixelOffset: new Cesium.Cartesian2(0, -50), // default: (0, 0)
          // eyeOffset: new Cesium.Cartesian3(0.0, 0.0, 0.0), // default
          // horizontalOrigin: Cesium.HorizontalOrigin.CENTER, // default
          // verticalOrigin: Cesium.VerticalOrigin.BOTTOM, // default: CENTER
          // scale: 2.0, // default: 1.0
          // color: Cesium.Color.LIME, // default: WHITE
          // rotation: Cesium.Math.PI_OVER_FOUR, // default: 0.0
          // alignedAxis: Cesium.Cartesian3.ZERO, // default
          width: 40, // default: undefined
          height: 40 // default: undefined
        }
      })
      viewer.camera.flyTo({
        destination: Cesium.Cartesian3.fromDegrees(121.54518, 38.927568, 6000.0),
        orientation: {
          heading: Cesium.Math.toRadians(0.0), // 默认朝北0度，顺时针方向，东是90度
          pitch: Cesium.Math.toRadians(-90), // 默认朝下看-90,0为水平看，
          roll: Cesium.Math.toRadians(0) // 默认0
        }
      })
    },
    /* *********************标点 end********************* */
    /* *********************绘制水面波浪效果 start********************* */
    drawWater() {
      // 而淹没效果需要将其设置为 true；当其值为 true 时，水面效果  会出现缝隙
      viewer.scene.globe.depthTestAgainstTerrain = false
      var waterFace = [
        130.0, 30.0, 0,
        150.0, 30.0, 0,
        150.0, 10.0, 0,
        130.0, 10.0, 0]
      var waterPrimitive = new Cesium.Primitive({
        show: true, // 默认隐藏
        allowPicking: false,
        geometryInstances: new Cesium.GeometryInstance({
          geometry: new Cesium.PolygonGeometry({
            polygonHierarchy: new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArrayHeights(waterFace))
            // extrudedHeight: 0,//注释掉此属性可以只显示水面
            // perPositionHeight : true//注释掉此属性水面就贴地了
          })
        }),
        // 可以设置内置的水面shader
        appearance: new Cesium.EllipsoidSurfaceAppearance({
          material: new Cesium.Material({
            fabric: {
              type: 'Water',
              uniforms: {
                // baseWaterColor:new Cesium.Color(0.0, 0.0, 1.0, 0.5),
                // blendColor: new Cesium.Color(0.0, 0.0, 1.0, 0.5),
                // specularMap: 'gray.jpg', //  着色器源码：float specularMapValue = texture2D(specularMap, materialInput.st).r;用于判断当前区域是否为水域
                normalMap: require('../../images/waterNormals.jpg'), // 水波动的法线纹理贴图
                frequency: 1000.0, // 波的数量
                animationSpeed: 0.01, // 水震动的速度
                amplitude: 10.0 // 振幅大小
              }
            }
          }),
          // 重写 shader，修改水面的透明度
          fragmentShaderSource: 'varying vec3 v_positionMC;\n' +
          'varying vec3 v_positionEC;\n' +
          'varying vec2 v_st;\n' +
          'void main()\n' +
          '{\n' +
          'czm_materialInput materialInput;\n' +
          'vec3 normalEC = normalize(czm_normal3D * czm_geodeticSurfaceNormal(v_positionMC, vec3(0.0), vec3(1.0)));\n' +
          '#ifdef FACE_FORWARD\n' +
          'normalEC = faceforward(normalEC, vec3(0.0, 0.0, 1.0), -normalEC);\n' +
          '#endif\n' +
          'materialInput.s = v_st.s;\n' +
          'materialInput.st = v_st;\n' +
          'materialInput.str = vec3(v_st, 0.0);\n' +
          'materialInput.normalEC = normalEC;\n' +
          'materialInput.tangentToEyeMatrix = czm_eastNorthUpToEyeCoordinates(v_positionMC, materialInput.normalEC);\n' +
          'vec3 positionToEyeEC = -v_positionEC;\n' +
          'materialInput.positionToEyeEC = positionToEyeEC;\n' +
          'czm_material material = czm_getMaterial(materialInput);\n' +
          '#ifdef FLAT\n' +
          'gl_FragColor = vec4(material.diffuse + material.emission, material.alpha);\n' +
          '#else\n' +
          'gl_FragColor = czm_phong(normalize(positionToEyeEC), material, czm_lightDirectionEC);\n' +
          'gl_FragColor.a=0.85;\n' +
          '#endif\n' +
          '}\n'
        })
      })
      viewer.scene.primitives.add(waterPrimitive)

      viewer.camera.flyTo({
        destination: Cesium.Cartesian3.fromDegrees(140, 20, 6000000.0),
        orientation: {
          heading: Cesium.Math.toRadians(0.0), // 默认朝北0度，顺时针方向，东是90度
          pitch: Cesium.Math.toRadians(-90), // 默认朝下看-90,0为水平看，
          roll: Cesium.Math.toRadians(0) // 默认0
        }
      })
    },
    /* *********************绘制水面波浪效果 end********************* */
    /* *********************热力图 start********************* */
    // 创建热力图
    createHeatMap(max, data) {
    // 创建元素
      var heatDoc = document.createElement('div')
      heatDoc.setAttribute('style', 'width:1000px;height:1000px;margin: 0px;display: none;')
      document.body.appendChild(heatDoc)
      // 创建热力图对象
      var heatmap = Heatmap.create({
        container: heatDoc,
        radius: 20,
        maxOpacity: 0.5,
        minOpacity: 0,
        blur: 0.75,
        gradient: {
          0.9: 'red',
          0.8: 'orange',
          0.7: 'yellow',
          0.5: 'blue',
          0.3: 'green'
        }
      })
      // 添加数据
      heatmap.setData({
        max: max,
        data: data
      })
      return heatmap
    },
    // 生成len个随机数据
    getData(len) {
    // 构建一些随机数据点
      var points = []
      var max = 0
      var width = 1000
      var height = 1000
      while (len--) {
        var val = Math.floor(Math.random() * 1000)
        max = Math.max(max, val)
        var point = {
          x: Math.floor(Math.random() * width),
          y: Math.floor(Math.random() * height),
          value: val
        }
        points.push(point)
      }
      return { max: max, data: points }
    },
    // 创建正方形 绑定热力图到视图中
    createRectangle(viewer, coordinate, heatMap) {
      viewer.entities.add({
        name: 'Rotating rectangle with rotating texture coordinate',
        show: true,
        rectangle: {
          coordinates: Cesium.Rectangle.fromDegrees(coordinate[0], coordinate[1], coordinate[2], coordinate[3]),
          material: heatMap._renderer.canvas // 核心语句，填充热力图
        }
      })

      viewer.camera.flyTo({
        destination: Cesium.Cartesian3.fromDegrees(-97.297503, 20.26468, 550000.0),
        orientation: {
          heading: Cesium.Math.toRadians(0.0), // 默认朝北0度，顺时针方向，东是90度
          pitch: Cesium.Math.toRadians(-90), // 默认朝下看-90,0为水平看，
          roll: Cesium.Math.toRadians(0) // 默认0
        }
      })
    },
    // 点击创建热力图 并旋转视图
    createThermodynamicDiagram() {
      var coordinate1 = [-109.0, 10.0, -80.0, 35.0]
      var heatMap1 = this.createHeatMap(this.getData(1000).max, this.getData(1000).data)
      this.createRectangle(viewer, coordinate1, heatMap1)
    }
    /* *********************热力图 end********************* */
  }
}

</script>
<style scoped>
.box{
  position: relative;
}
.option{
  position: absolute;
  width: 100%;
  height: 60px;
  line-height: 60px;
  top: 0;
  right: 0;
  border: 1px solid #ffffff;
  z-index: 2000;
}
button{
  padding: 6px 12px;
  cursor: pointer;
  margin-left: 10px;
  border: none;
  background: #ffffff;
  color: #333333;
}
#cesiumContainer {
  width: 100%;
  height: 100%;
}
</style>
